/*
 * A simple ToDo Manager
 *
 * Copyright (c) 2011 Nosheen Zaza, Manuel Rebollo, Seyedsaeid Mahpeikar and
 * Wo Ke
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package todomanager.ui.tableview;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.Comparator;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import todomanager.model.Task;

/**
 * Provides a table view for a list of tasks.
 * 
 * @author
 * Nosheen Zaza
 */
public class TaskDisplayTable extends JTable {

    private TaskCellRenderer taskCellRenderer;
    private TaskCellEditor taskCellEditor;

    /**
     * Creates and initializes a new instance.
     */
    public TaskDisplayTable() {
        init();
    }

    /**
     * Creates and initializes a new instance, with the given {@code TaskTableModel}.
     * @param ttm a a {@code TaskTableModel}
     */
    public TaskDisplayTable(TaskTableModel ttm) {
        super(ttm);
        init();

    }

    /**
     * Initializes the table.
     */
    private void init() {
        taskCellRenderer = new TaskCellRenderer();
        taskCellEditor = new TaskCellEditor();

        setDefaultRenderer(Task.class, taskCellRenderer);
        setDefaultEditor(Task.class, taskCellEditor);

        getTableHeader().setFont(new Font("Dialog", Font.BOLD, 13));
        getTableHeader().setForeground(new Color(0, 130, 0));
        getTableHeader().setReorderingAllowed(false);

        // Align column headers to the left.
        JLabel label = (JLabel)getTableHeader().getDefaultRenderer();;
        label.setHorizontalAlignment(JLabel.LEFT);

        setRowHeight(55);
        setOpaque(false);
        this.setGridColor(UIManager.getColor("Color.Table-Grid"));
    }

    /**
     * Sets up the renderer of the table.
     * @param renderer
     * @param row
     * @param column
     * @return A table renderer.
     */
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);
        /*
         * We want renderer component to be transparent
         * so the background image is visible
         */
        if (c instanceof JComponent) {
            ((JComponent) c).setOpaque(false);
        }

        //Fit the first column to the the largest cell
        TableColumn tableColumn = getColumnModel().getColumn(column);

        tableColumn.setPreferredWidth(Math.max(
                c.getPreferredSize().width,
                tableColumn.getPreferredWidth()));
        
        getColumnModel().getColumn(1).setMaxWidth(100);
        getColumnModel().getColumn(1).setPreferredWidth(90);
        getColumnModel().getColumn(2).setMaxWidth(80);
        getColumnModel().getColumn(2).setPreferredWidth(80);

        return c;
    }

    /**
     * Custom task date comparator, with special handling to null dates.
     */
    private class TaskDateComparator implements Comparator<Task> {

        public int compare(Task o1, Task o2) {
            // We consider null the smallest value.
            if (o1.getDueDate() == null && o2.getDueDate() == null)
                    return 0;
            if(o1.getDueDate() == null)
                return -1;
            if(o2.getDueDate() == null)
                return 1;
            if(o1.getDueDate().after(o2.getDueDate()))
                return 1;
            if(o1.getDueDate().before(o2.getDueDate()))
                return -1;
            else
                return 0;
        }
    }

    /**
     * Custom task priority comparator.
     */
    private class TaskPriorityComparator implements Comparator<Task> {

        public int compare(Task o1, Task o2) {
           return o1.getPriority().compareTo(o2.getPriority());
        }
    }

    /**
     * Custom task category comparator.
     */
    private class TaskCategoryComparator implements Comparator<Task> {

        public int compare(Task o1, Task o2) {
           return o1.getCategory().compareTo(o2.getCategory());
        }
    }

    /**
     * Sets the table's model, also assigns a suitable sorter to each column
     * of the model.
     * @param model
     */
    @Override
    public void setModel(TableModel model) {
        super.setModel(model);
        changeSorter();

    }

    /**
     * Creates comparators and assigns them to the table model columns.
     */
    private void changeSorter() {
        TableRowSorter sorter = new TableRowSorter(getModel());
        sorter.setComparator(0, new TaskDateComparator());
        sorter.setComparator(1, new TaskCategoryComparator());
        sorter.setComparator(2, new TaskPriorityComparator());
        setRowSorter(sorter);
    }
}
